package com.erge.student.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import com.erge.common.utils.BeanCopyUtils;
import com.erge.common.utils.DateUtils;
import com.erge.common.utils.SecurityUtils;
import com.erge.student.domain.bo.TreeNode;
import com.erge.student.domain.vo.ClassVO;
import org.springframework.stereotype.Service;
import com.erge.student.mapper.ClassMapper;
import com.erge.student.domain.ClassDO;
import com.erge.student.service.IClassService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;

/**
 * 班级Service业务层处理
 *
 * @author roydon
 * @date 2025-05-22
 */
@RequiredArgsConstructor
@Service
public class ClassServiceImpl extends ServiceImpl<ClassMapper, ClassDO> implements IClassService {
    private final ClassMapper classMapper;

    /**
     * 查询班级
     *
     * @param id 班级主键
     * @return 班级
     */
    @Override
    public ClassDO selectClassById(Long id) {
        return classMapper.selectClassById(id);
    }

    /**
     * 查询班级列表
     *
     * @param classDO 班级
     * @return 班级
     */
    @Override
    public List<ClassDO> selectClassList(ClassDO classDO) {
        return classMapper.selectClassList(classDO);
    }

    /**
     * 新增班级
     *
     * @param classDO 班级
     * @return 结果
     */
    @Override
    public int insertClass(ClassDO classDO) {
        classDO.setCreateBy(SecurityUtils.getUsername());
        classDO.setCreateTime(DateUtils.getNowDate());
        return classMapper.insertClass(classDO);
    }

    /**
     * 修改班级
     *
     * @param classDO 班级
     * @return 结果
     */
    @Override
    public int updateClass(ClassDO classDO) {
        classDO.setUpdateBy(SecurityUtils.getUsername());
        classDO.setUpdateTime(DateUtils.getNowDate());
        return classMapper.updateClass(classDO);
    }

    /**
     * 批量删除班级
     *
     * @param ids 需要删除的班级主键
     * @return 结果
     */
    @Override
    public int deleteClassByIds(Long[] ids) {
        return classMapper.deleteClassByIds(ids);
    }

    /**
     * 删除班级信息
     *
     * @param id 班级主键
     * @return 结果
     */
    @Override
    public int deleteClassById(Long id) {
        return classMapper.deleteClassById(id);
    }

    @Override
    public List<TreeNode> classTree(ClassDO classDO) {
        List<ClassDO> classDOS = classMapper.selectClassList(classDO);
        List<ClassVO> orgVOList = BeanCopyUtils.copyBeanList(classDOS, ClassVO.class);
        List<ClassVO> orgVOList1 = buildTree(orgVOList);
        return orgVOList1.stream().map(TreeNode::new).collect(Collectors.toList());
    }

    public List<ClassVO> buildTree(List<ClassVO> list) {
        List<ClassVO> returnList = new ArrayList<>();
        List<Long> tempList = new ArrayList<>();
        for (ClassVO dept : list) {
            tempList.add(dept.getId());
        }
        for (ClassVO d : list) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(d.getParentId())) {
                recursionFn(list, d);
                returnList.add(d);
            }
        }
        if (returnList.isEmpty()) {
            returnList = list;
        }
        return returnList;
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<ClassVO> list, ClassVO t) {
        // 得到子节点列表
        List<ClassVO> childList = getChildList(list, t);
        t.setChildren(childList);
        for (ClassVO tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<ClassVO> getChildList(List<ClassVO> list, ClassVO t) {
        List<ClassVO> tlist = new ArrayList<>();
        Iterator<ClassVO> it = list.iterator();
        while (it.hasNext()) {
            ClassVO n = (ClassVO) it.next();
            if (Objects.nonNull(n.getParentId()) && n.getParentId().equals(t.getId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<ClassVO> list, ClassVO t) {
        return !getChildList(list, t).isEmpty();
    }
}
